fn main() {
  //1、 类似于C语言的方式定义
  enum IpAddrKind {
    V4,
    V6
  }
  struct IpAddr {
    kind: IpAddrKind,
    address: String
  }
  let i1 = IpAddr {
    kind: IpAddrKind::V4,
    address: String::from("127.0.0.1")
  };
  let i2 = IpAddr {
    kind: IpAddrKind::V6,
    address: String::from("::1")
  };

  //2、 rust语言提倡的定义方式
  #[derive(Debug)]
  enum IpAddr2 {
    V4(String),
    V6(String)
  };
  let i1 = IpAddr2::V4(String::from("127.0.0.1"));
  let i2 = IpAddr2::V6(String::from("::1"));
  println!("{:#?}", i1);
/*
V4(
    "127.0.0.1",
)
*/
  println!("{:#?}", i2);
/*
V6(
    "::1",
)
*/
  //
  //3. 可以是不同类型
  #[derive(Debug)]
  enum IpAddr3 {
    V4(u8,u8,u8,u8),
    V6(String)
  };
  let i1 = IpAddr3::V4(127, 0, 0, 1);

  //4. 经典用法
  enum Message {
    Quit,
    Move {x: i32,y: i32},
    Write(String),
    Change(i32,i32,i32)
  };
  //等同于
  //struct QuitMessage
  //struct MoveMessage {x: i32,y: i32}
  //struct WriteMessage (String)
  //struct Change (i32,i32,i32)

  //5. 枚举类型的方法 以及 match
  impl Message {
    fn print(&self) {
      //类似于switch case
      match self {
        Message::Quit => println!("Quit"),
        Message::Move{x, y}=> println!("Move x = {}, y = {}", x, y),
        Message::Change(a, b, c) => println!("Change a = {}, b = {}, c = {}", a, b, c),
        Message::Write(s) => println!("Write = {}",s)
      }
    }
  };
  let quit = Message::Quit;
  quit.print(); //Quit
  let mo = Message::Move { x: 10, y: 20 };
  mo.print(); //Move x = 10, y = 20
  let change = Message::Change(1,2,3);
  change.print(); //Change a = 1, b = 2, c = 3
}
